package com.sj.purchase.modules.cost.web;

import com.sj.purchase.modules.cost.domain.imei.Inventory;
import com.sj.purchase.modules.cost.domain.order.OutOrder;
import com.sj.purchase.modules.cost.repository.imei.InventoryRepository;
import com.sj.purchase.modules.cost.repository.order.OutOrderRepository;
import com.sj.purchase.modules.cost.service.order.OutOrderItemCostService;
import com.sj.purchase.modules.cost.views.out_order.ExcelOutOrderNos;
import com.sj.purchase.modules.cost.views.out_order.OutOrderCostVO;
import com.sj.purchase.modules.cost.views.out_order.OutOrderNos;
import com.sj.purchase.util.ExcelDownloadUtil;
import com.sj.purchase.util.excel.annotation.ExcelCell;
import com.sj.purchase.util.excel.annotation.ExcelSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Alin on 2017/11/24.
 */
@RestController
@RequestMapping("api/out-order-item-cost")
public class OutOrderItemCostController {
    @Autowired
    private OutOrderItemCostService outOrderItemCostService;

    @Autowired
    private OutOrderRepository outOrderRepository;

    @Autowired
    private InventoryRepository inventoryRepository;

    private List<OutOrderCostVO> outOrderCostVOS = new ArrayList<>();

    @GetMapping
    public ResponseEntity searchDate(String orderNo, Date startDate, Date endDate, Pageable pageable) {
        return ResponseEntity.ok(outOrderItemCostService.search(orderNo, startDate, endDate, pageable));
    }

    @GetMapping("/excel")
    public void excel(String orderNo, Date startDate, Date endDate) {
        ExcelDownloadUtil.easyPoi("订单明细成本", OutOrderCostVO.class, outOrderItemCostService.search(orderNo, startDate, endDate, null).getContent().stream().collect(Collectors.toList()));
    }

    @RequestMapping("/upload")
    public ResponseEntity upload(@RequestParam("excel") MultipartFile multFile){
        InputStream inputStream = null;
        try {
            inputStream = multFile.getInputStream();
            String uFileName = multFile.getOriginalFilename();
            ExcelOutOrderNos outOrderNos = importExcel(uFileName,inputStream, ExcelOutOrderNos.class);
            return ResponseEntity.ok(outOrderNos.getOutOrderNos());
        } catch (Exception e) {
            return ResponseEntity.ok("上传失败");
        }
    }

    @PostMapping("/outOrder")
    public void getOutOrder(@RequestBody List<OutOrderNos> orderNos){
        Set<String> set = new HashSet<>();
        orderNos.forEach(outOrderNos -> {
            set.add(outOrderNos.getOutOrderNos());
        });
        set.remove("");
        String[] orderNo = set.toArray(new String[set.size()]);
        List<OutOrder> outOrders = outOrderRepository.findByOrderNoIn(orderNo);
        List<Inventory> inventories = inventoryRepository.findByOutOrderNoIn(orderNo);
        outOrderCostVOS = outOrderItemCostService.getList(inventories,outOrders);
    }

    /**
     * 判断后台处理数据是否完成
     */
    @GetMapping("/isCheck")
    public ResponseEntity getSize(){
        String isCheck = !outOrderCostVOS.isEmpty() ? "success":"error";
        return ResponseEntity.ok(isCheck);
    }

    @GetMapping("/export")
    public void export(){
        ExcelDownloadUtil.easyPoi("交易单号明细",OutOrderCostVO.class,outOrderCostVOS);
        outOrderCostVOS.clear();
    }

    /**
     * 导入表生成集合
     *
     * @param inputStream
     * @param excelClazz
     * @param <T>
     * @return
     * @throws IOException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private <T> T importExcel(String fileName,InputStream inputStream, Class<? extends T> excelClazz) throws IOException, InstantiationException, IllegalAccessException {
        String type = fileName.substring(fileName.lastIndexOf("."));
        Workbook workbook = null;
        if (type.equals(".xls")){
            workbook =  new HSSFWorkbook(inputStream);
        }if (".xlsx".equals(type)){
            workbook = new XSSFWorkbook(inputStream);
        }
        Object excelObj = excelClazz.newInstance();//实例化对象
        Field[] fields = excelClazz.getDeclaredFields();//获取类中所有的属性
        for (Field field : fields) {
            if (field.isAnnotationPresent(ExcelSheet.class)) {
                ExcelSheet sheet = field.getAnnotation(ExcelSheet.class);
//       默认只支持 List
                ParameterizedType pt = (ParameterizedType) field.getGenericType();
                Class clz = (Class) pt.getActualTypeArguments()[0];
                field.setAccessible(true);
                field.set(excelObj, this.sheet(workbook, sheet.value(), clz));
            }
        }
        return (T) excelObj;
    }

    /**
     * 获取表中的Sheet数据生成list
     *
     * @param workbook
     * @param sheetIndex
     * @param clazz
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    private List<? super Object> sheet(Workbook workbook, int sheetIndex, Class<?> clazz) throws IllegalAccessException, InstantiationException {
        Sheet sheet = workbook.getSheetAt(sheetIndex);
        List<? super Object> rowList = new ArrayList<>(sheet.getLastRowNum());
        Field[] fields = clazz.getDeclaredFields();
        for (int j = 0; j < sheet.getLastRowNum() + 1; j++) {// getLastRowNum，获取最后一行的行标
            Object o = clazz.newInstance();
            rowList.add(o);
            Row row = sheet.getRow(j);
            for (Field field : fields) {
                if (field.isAnnotationPresent(ExcelCell.class)) {
                    ExcelCell excelCell = field.getAnnotation(ExcelCell.class);
                    int cellIndex = excelCell.value();
                    if (row != null) {
                        if (row.getCell(cellIndex) != null) {
                            row.getCell(cellIndex).setCellType(Cell.CELL_TYPE_STRING);
                        }
                        if (row.getCell(cellIndex) != null && !row.getCell(cellIndex).equals("")) {
                            String cellValue = row.getCell(cellIndex).getStringCellValue();
                            field.setAccessible(true);
                            field.set(o, cellValue);
                        }
                    }
                }
            }
        }
        return rowList;
    }
}
